package org.stream.answerduel.service;

import io.jsonwebtoken.Claims;
import net.sf.json.JSONObject;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import org.stream.answerduel.dto.PageResult;
import org.stream.answerduel.entity.User;
import org.stream.answerduel.repository.UserRepository;
import org.stream.answerduel.util.Constant;
import org.stream.answerduel.util.JwtUtil;
import org.stream.answerduel.util.SnowflakeIdWorker;
import org.stream.answerduel.vo.FriendVo;
import org.stream.answerduel.vo.UserVo;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.NoSuchElementException;

/**
 * @author 郭榕
 * @date  2019/7/5 11:00
 * 功能描述： 对用户操作的业务逻辑
 *
 */
@Service
public class UserService {

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private SnowflakeIdWorker snowflakeIdWorker;

    /**
     * 功能描述：插入用户
     * @param userVo
     */
    public void add(UserVo userVo) {
        User user = new User();
        BeanUtils.copyProperties(userVo, user);
        user.setId(snowflakeIdWorker.nextId());
        user.setCreateBy(user.getId());
        user.setCreateAt(new Date());
        user.setUpdateBy(user.getId());
        user.setUpdateAt(new Date());
        userRepository.save(user);
        BeanUtils.copyProperties(user, userVo);
    }

    /**
     * 功能描述：删除用户
     *
     * @param id
     */
    public void del(Long id) {
        userRepository.deleteById(id);
    }

    /**
     * 功能描述：分页查询用户列表
     * @param pageSize
     * @param pageNumber
     */
    public PageResult<UserVo> select(Integer pageNumber, Integer pageSize) {

        Page<User> page = userRepository.findAll(PageRequest.of(pageNumber, pageSize));

        List<UserVo> list = new ArrayList<>();
        for (User user : page.getContent()) {
            UserVo userVo = new UserVo();
            BeanUtils.copyProperties(user, userVo);
            list.add(userVo);
        }

        return new PageResult<UserVo>(pageNumber, pageSize, page.getTotalPages(), list);
    }

    /**
     * 功能描述：更新用户信息
     * @param userVo
     */
    public void update(UserVo userVo) {
        User user = userRepository.findById(userVo.getId()).get();
        BeanUtils.copyProperties(userVo, user);
        user.setUpdateBy(userVo.getId());
        user.setUpdateAt(new Date());
        userRepository.save(user);
    }

    /**
     *
     * @author 郭榕
     * @date   2019/7/11 11:29
     * 功能描述：根据微信id查询单个用户
     * @param  wechatid
     */
    public UserVo findOneUserByWechatId(String wechatid)
    {
        return changeInUserVo(userRepository.findByWechatID(wechatid));
    }

    /**
     *
     * @author 郭榕
     * @date   2019/7/13 9:45
     * 功能描述：根据id查询该用户
     * @param  userid
     * @return UserVo
     */
    public UserVo findOneUserByUserid(Long userid)
    {
        User user = null;
        try{
            user = userRepository.findById(userid).get();
        }
        catch(NoSuchElementException e){
            return null;
        }
        return changeInUserVo(user);
    }

    /**
     *
     * @author 郭榕
     * @date   2019/7/12 11:29
     * 功能描述：根据微信id查询好友列表
     * @param  wechatid
     */
    public List<FriendVo> findFriendsByWechatid(String wechatid)
    {
        List<User> users = userRepository.findFriendsByWechatId(wechatid);
        List<FriendVo> friendVos = new ArrayList<>();
        for(User user : users ){
            FriendVo friendVo = new FriendVo();
            friendVo.setUserId(user.getId());
            friendVo.setWechatID(user.getWechatID());
            friendVo.setNickName(user.getNickName());
            friendVo.setScore(user.getScore());
            friendVo.setAvatarUrl(user.getAvatarUrl());
            friendVos.add(friendVo);
        }
        return friendVos;
    }
    /**
     * @author 郭榕
     * @date   2019/7/12 19:14
     * 功能描述：将user信息封装成UserVo
     * @param user
     * @return
     */
    public UserVo changeInUserVo(User user){
        UserVo userVo = new UserVo();
        BeanUtils.copyProperties(user, userVo);
        return userVo;
    }
    /**
     * @author  郭榕
     * @date 2019/7/12 19:32
     * 功能描述 ： 查询用户是否存在，如果不存在则插入数据库，并返回，如果存在则直接返回;
     * @param  wechatId,nickName,avatarUrl,token
     * @return UserVo
     */
    public UserVo checkUserExist(String wechatId , String nickName , String avatarUrl ,String sessionKey) throws Exception {

        List<User> users = userRepository.findAll();
        JSONObject jsonObject= new JSONObject();
        jsonObject.put("openId" , wechatId);
        jsonObject.put("sessionKey" , sessionKey);
        String subject = jsonObject.toString();
        //System.out.println(userVo.getId());
        //拿session_id和open_id生成token
        String jwt = JwtUtil.createJWT(Constant.JWT_ID, "GGGR", subject, Constant.JWT_TTL);
        for(User u : users)
        {
            if(u.getWechatID().equals(wechatId))
            {
               UserVo userVo = changeInUserVo(u);
               //更新token
               userVo.setToken(jwt);
               this.update(userVo);
               return userVo;
            }
        }
        UserVo userVo = new UserVo();
        userVo.setWechatID(wechatId);
        userVo.setNickName(nickName);
        // String jwt = util.createJWT(Constant.JWT_ID, "GGGR", subject, Constant.JWT_TTL);
        //需要添加token
        userVo.setToken(jwt);
        if(avatarUrl == null || avatarUrl == "")
            userVo.setAvatarUrl("/static/images/user.png");
        else
            userVo.setAvatarUrl(avatarUrl);
        this.add(userVo);
        return userVo;
    }

    /**
     * 刷新token
     * @param token
     *
     */
    public void flushToken(String token) throws Exception {
        //第一步=============================================
        //先将所传入的旧的token解码;
        Claims claims = JwtUtil.parseJWT(token);
        String subjectKey = claims.getSubject();
        //System.out.println(subjectKey);
        com.alibaba.fastjson.JSONObject json = com.alibaba.fastjson.JSONObject.parseObject(subjectKey);
        //获取生成token所需的sessionKey和openId,并根据openId也即是微信id获得用户信息;
        String sessionKey = json.get("sessionKey").toString();
        String openId    = json.get("openId").toString();
        User user = userRepository.findByWechatID(openId);
        UserVo userVo = this.changeInUserVo(user);

        //第二步============================================
        //根据得到的sessionKey和openId生成新的token,并存入数据库。
        JSONObject jsonObject= new JSONObject();
        jsonObject.put("openId" , openId);
        jsonObject.put("sessionKey" , sessionKey);
        String subject = jsonObject.toString();
        //拿session_id和open_id生成token
        String jwt = JwtUtil.createJWT(Constant.JWT_ID, "GGGR", subject, Constant.JWT_TTL);
        userVo.setToken(jwt);
        //System.out.println(userVo);
        this.update(userVo);
    }

    //打印解密的token
    public void checkToken(String token) throws Exception {
        Claims c = JwtUtil.parseJWT(token);
        System.out.println("解密如下:");
        System.out.println(c.getId());
        System.out.println(c.getIssuedAt());
        System.out.println(c.getSubject());
        System.out.println(c.getIssuer());
        System.out.println(c.get("user_id", String.class));

    }

}